<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Magic Wand Tool</title>
    <style>
        canvas {
            border: 1px solid black;
        }

        button {
            margin-top: 10px;
        }
    </style>
</head>

<body>
    <canvas id="canvas" width="800" height="600"></canvas>
    <button id="toggleEraser">Enable Magic Wand</button>
    <script>
        document.addEventListener('DOMContentLoaded', () => {
            const canvas = document.getElementById('canvas');
            const ctx = canvas.getContext('2d');
            const button = document.getElementById('toggleEraser');
            let isEraserActive = false;
            const tolerance = 100; // 颜色相似度容忍度

            button.addEventListener('click', () => {
                isEraserActive = !isEraserActive;
                button.textContent = isEraserActive ? 'Disable Magic Wand' : 'Enable Magic Wand';
            });

            function loadImage(url) {
                return new Promise((resolve, reject) => {
                    const img = new Image();
                    img.crossOrigin = "Anonymous"; // 避免跨域问题
                    img.onload = () => resolve(img);
                    img.onerror = reject;
                    img.src = url;
                });
            }

            function rgbToLab(r, g, b) {
                r /= 255; g /= 255; b /= 255;
                r = r > 0.04045 ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92;
                g = g > 0.04045 ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92;
                b = b > 0.04045 ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92;
                let x = (r * 0.4124564 + g * 0.3575761 + b * 0.1804375) / 0.95047;
                let y = (r * 0.2126729 + g * 0.7151522 + b * 0.0721750) / 1.00000;
                let z = (r * 0.0193339 + g * 0.1191920 + b * 0.9503041) / 1.08883;
                x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + 16 / 116;
                y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + 16 / 116;
                z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + 16 / 116;
                return [(116 * y) - 16, 500 * (x - y), 200 * (y - z)];
            }

            function deltaE(lab1, lab2) {
                return Math.sqrt(
                    Math.pow(lab2[0] - lab1[0], 2) +
                    Math.pow(lab2[1] - lab1[1], 2) +
                    Math.pow(lab2[2] - lab1[2], 2)
                );
            }

            function getColorDistance(color1, color2) {
                const lab1 = rgbToLab(
                    (color1 >> 16) & 0xff,
                    (color1 >> 8) & 0xff,
                    color1 & 0xff
                );
                const lab2 = rgbToLab(
                    (color2 >> 16) & 0xff,
                    (color2 >> 8) & 0xff,
                    color2 & 0xff
                );
                return deltaE(lab1, lab2);
            }

            function floodFill(imageData, x, y, targetColor, replacementColor) {
                const stack = [[x, y]];
                const width = imageData.width;
                const height = imageData.height;
                const data = imageData.data;
                const visited = new Uint8Array(width * height);

                function getColorAt(x, y) {
                    const index = (y * width + x) * 4;
                    return (data[index] << 16) | (data[index + 1] << 8) | data[index + 2];
                }

                function setColorAt(x, y, color) {
                    const index = (y * width + x) * 4;
                    data[index] = (color >> 16) & 0xff;
                    data[index + 1] = (color >> 8) & 0xff;
                    data[index + 2] = color & 0xff;
                    data[index + 3] = 0; // 设置为透明
                }

                while (stack.length > 0) {
                    const [cx, cy] = stack.pop();
                    if (cx < 0 || cx >= width || cy < 0 || cy >= height) continue;

                    const idx = cy * width + cx;
                    if (visited[idx]) continue;
                    visited[idx] = 1;

                    const currentColor = getColorAt(cx, cy);
                    if (getColorDistance(currentColor, targetColor) > tolerance) continue;

                    setColorAt(cx, cy, replacementColor);

                    stack.push([cx + 1, cy]);
                    stack.push([cx - 1, cy]);
                    stack.push([cx, cy + 1]);
                    stack.push([cx, cy - 1]);
                }
            }

            canvas.addEventListener('click', (e) => {
                if (!isEraserActive) return;

                const rect = canvas.getBoundingClientRect();
                const x = Math.floor(e.clientX - rect.left);
                const y = Math.floor(e.clientY - rect.top);

                const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
                const targetColor = (imageData.data[(y * canvas.width + x) * 4] << 16) |
                    (imageData.data[(y * canvas.width + x) * 4 + 1] << 8) |
                    imageData.data[(y * canvas.width + x) * 4 + 2];
                const replacementColor = 0x000000; // 透明颜色

                floodFill(imageData, x, y, targetColor, replacementColor);
                ctx.putImageData(imageData, 0, 0);
            });

            loadImage('./1.png').then(img => {
                // 计算图像的纵横比
                const aspectRatio = img.width / img.height;
                const canvasAspectRatio = canvas.width / canvas.height;

                // 调整图像尺寸以适应画布
                if (aspectRatio > canvasAspectRatio) {
                    const height = canvas.width / aspectRatio;
                    ctx.drawImage(img, 0, (canvas.height - height) / 2, canvas.width, height);
                } else {
                    const width = canvas.height * aspectRatio;
                    ctx.drawImage(img, (canvas.width - width) / 2, 0, width, canvas.height);
                }
            }).catch(err => {
                console.error('Failed to load image:', err);
            });
        });
    </script>
</body>

</html>